package com.ruoyi.sycs.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjUtil;
import com.baomidou.dynamic.datasource.annotation.DSTransactional;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.domain.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.ruoyi.sycs.domain.BaFanganDetail;
import com.ruoyi.sycs.domain.FanganUseInfo;
import com.ruoyi.sycs.domain.bo.UseFanganQueryBo;
import com.ruoyi.sycs.domain.vo.BaFanganDetailVo;
import com.ruoyi.sycs.domain.vo.BaFanganYuesheVo;
import com.ruoyi.sycs.domain.vo.FanganUseInfoVo;
import com.ruoyi.sycs.mapper.BaFanganDetailMapper;
import com.ruoyi.sycs.mapper.FanganUseInfoMapper;
import com.ruoyi.sycs.service.IFanganUseInfoService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import com.ruoyi.sycs.domain.bo.BsFanganInfoBo;
import com.ruoyi.sycs.domain.vo.BsFanganInfoVo;
import com.ruoyi.sycs.domain.BsFanganInfo;
import com.ruoyi.sycs.mapper.BsFanganInfoMapper;
import com.ruoyi.sycs.service.IBsFanganInfoService;

import java.util.List;
import java.util.Map;
import java.util.Collection;

/**
 * 小数点方案管理Service业务层处理
 *
 * @author zyb
 * @date 2024-10-17
 */
@RequiredArgsConstructor
@Service
@DSTransactional
public class BsFanganInfoServiceImpl implements IBsFanganInfoService {

    private final BsFanganInfoMapper baseMapper;
    private final BaFanganDetailMapper detailMapper;
    private final FanganUseInfoMapper fanganUseInfoMapper;

    /**
     * 查询小数点方案管理
     */
    @Override
    public BsFanganInfoVo queryById(Long fanganId){
        BsFanganInfoVo bsFanganInfoVo = baseMapper.selectVoById(fanganId);
        // detail
        List<BaFanganDetailVo> detailVos = detailMapper.selectVoList(new LambdaQueryWrapper<BaFanganDetail>()
            .eq(BaFanganDetail::getFanganId, fanganId));
        bsFanganInfoVo.setDetailVos(detailVos);
        return bsFanganInfoVo;
    }

    /**
     * 查询小数点方案管理列表
     */
    @Override
    public TableDataInfo<BsFanganInfoVo> queryPageList(BsFanganInfoBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<BsFanganInfo> lqw = buildQueryWrapper(bo);
        Page<BsFanganInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);

        if (ObjUtil.isNotNull(bo.getExcelId())) {
            FanganUseInfoVo fanganUseInfoVo = fanganUseInfoMapper.selectVoOne(new LambdaQueryWrapper<FanganUseInfo>()
                .eq(FanganUseInfo::getExcelId, bo.getExcelId()));
            if (ObjUtil.isNotNull(fanganUseInfoVo)) {
                result.getRecords().forEach(v->{
                    // excelId正在使用
                    if (v.getFanganId().equals(fanganUseInfoVo.getFanganId())) {
                        v.setExcelIdUseFlag(true);
                    }
                });
            }
        }
        return TableDataInfo.build(result);
    }

    /**
     * 查询小数点方案管理列表
     */
    @Override
    public List<BsFanganInfoVo> queryList(BsFanganInfoBo bo) {
        LambdaQueryWrapper<BsFanganInfo> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<BsFanganInfo> buildQueryWrapper(BsFanganInfoBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<BsFanganInfo> lqw = Wrappers.lambdaQuery();
        lqw.apply(bo.getDeptId() != null, "(dept_id = {0} or dept_id is Null)", bo.getDeptId());
        lqw.eq(bo.getDefaultFlag() != null, BsFanganInfo::getDefaultFlag, bo.getDefaultFlag());
        lqw.eq(bo.getExcelTypeId() != null, BsFanganInfo::getExcelTypeId, bo.getExcelTypeId());
        lqw.eq(StringUtils.isNotBlank(bo.getSysYesNo()), BsFanganInfo::getSysYesNo, bo.getSysYesNo());
        lqw.eq(StringUtils.isNotBlank(bo.getFanganName()), BsFanganInfo::getFanganName, bo.getFanganName());
        lqw.eq(bo.getSyTypeId() != null, BsFanganInfo::getSyTypeId, bo.getSyTypeId());
        lqw.eq(StringUtils.isNotBlank(bo.getLabel()), BsFanganInfo::getLabel, bo.getLabel());
        return lqw;
    }

    /**
     * 新增小数点方案
     */
    @Override
    public Boolean insertByBo(BsFanganInfoBo bo) {
        BsFanganInfo add = BeanUtil.toBean(bo, BsFanganInfo.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setFanganId(add.getFanganId());
            // add detail
            if (CollUtil.isEmpty(bo.getDetailVos())) {
                throw new ServiceException("  没有方案明细，不能创建方案");
            }
            List<BaFanganDetail> baFanganDetails = BeanUtil.copyToList(bo.getDetailVos(), BaFanganDetail.class);
            baFanganDetails.forEach(v->{
                v.setFanganId(add.getFanganId());
            });
            return detailMapper.insertBatch(baFanganDetails);
        }
        return flag;
    }

    /**
     * 修改小数点方案
     */
    @Override
    public Boolean updateByBo(BsFanganInfoBo bo) {
        // 这两个字段，不允许修改
        bo.setSysYesNo(null);
        bo.setDefaultFlag(null);

        BsFanganInfo update = BeanUtil.toBean(bo, BsFanganInfo.class);
        validEntityBeforeSave(update);
//        if ("Y".equals(bo.getSysYesNo())) {
//            throw new ServiceException("系统级默认方案不允许修改");
//        }
        boolean flag = baseMapper.updateById(update) > 0;
        if (flag) {
            // delete and insert detail
            detailMapper.delete(new LambdaQueryWrapper<BaFanganDetail>().eq(BaFanganDetail::getFanganId, bo.getFanganId()));
            List<BaFanganDetail> baFanganDetails = BeanUtil.copyToList(bo.getDetailVos(), BaFanganDetail.class);
            baFanganDetails.forEach(v->{
                v.setFanganId(bo.getFanganId());
            });
            return detailMapper.insertBatch(baFanganDetails);
        }
        return flag;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(BsFanganInfo entity){
        //TODO 做一些数据校验,如唯一约束
        if ("Y".equals(entity.getSysYesNo())) {
            entity.setDeptId(null); // 因为系统级默认方案，不属于任何一个dept
            if (baseMapper.exists(new LambdaQueryWrapper<BsFanganInfo>()
                .eq(BsFanganInfo::getExcelTypeId, entity.getExcelTypeId())
                .eq(BsFanganInfo::getSysYesNo, "Y")
                .ne(ObjUtil.isNotNull(entity.getFanganId()), BsFanganInfo::getFanganId, entity.getFanganId()))) {
                throw new ServiceException("  一个 excelTypeId 的  系统级默认方案，最多只有一个。");
            }
            // add sysFangan
        }
//        else {
////            //  如果是 这个 deptId 和  excelTypeId 没有任何方案 是(首次添加)，则接口内部自动将其设为试验室默认。
////            if (!baseMapper.exists(new LambdaQueryWrapper<BsFanganInfo>()
////                .eq(BsFanganInfo::getDeptId, entity.getDeptId())
////                .eq(BsFanganInfo::getExcelTypeId, entity.getExcelTypeId()))) {
////                entity.setDefaultFlag(1);
////            }
//        }
    }

    /**
     * 批量删除小数点方案管理
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        // delete detail
        detailMapper.delete(new LambdaQueryWrapper<BaFanganDetail>().in(BaFanganDetail::getFanganId, ids));

        boolean flag = baseMapper.deleteBatchIds(ids) > 0;

        // 删除对这些方案的使用情况
        fanganUseInfoMapper.delete(new LambdaQueryWrapper<FanganUseInfo>()
            .in(FanganUseInfo::getFanganId, ids));
        return flag;
    }

    /**
     * 设为试验室默认方案
     */
    @Override
    public Boolean setDefault(Long fanganId) {
        BsFanganInfoVo bsFanganInfoVo = queryById(fanganId);
        if ("Y".equals(bsFanganInfoVo.getSysYesNo())) {
            throw new ServiceException("系统默认方案不允许设为试验室默认方案");
        }
        Assert.notNull(bsFanganInfoVo.getDeptId(), "bsFanganInfoVo.getDeptId() is null");
        Assert.notNull(bsFanganInfoVo.getExcelTypeId(), "bsFanganInfoVo.getExcelTypeId() is null");
        // 1 set default
        baseMapper.update(null, new LambdaUpdateWrapper<BsFanganInfo>()
            .set(BsFanganInfo::getDefaultFlag, 1).eq(BsFanganInfo::getFanganId, fanganId));
        // 2. set not default for other
        baseMapper.update(null, new LambdaUpdateWrapper<BsFanganInfo>()
            .set(BsFanganInfo::getDefaultFlag, 0)
            .eq(BsFanganInfo::getDeptId, bsFanganInfoVo.getDeptId())
            .eq(BsFanganInfo::getExcelTypeId, bsFanganInfoVo.getExcelTypeId())
            .ne(BsFanganInfo::getFanganId, fanganId));
        return Boolean.TRUE;
    }

    /**
     *  新增方案时，获取方案详细的预设字段信息（新增方案前调用）
     */
    @Override
    public List<BaFanganYuesheVo> getYusheInfo(BsFanganInfoBo bo) {
        BsFanganInfoVo sysFangan = baseMapper.selectVoOne(new LambdaQueryWrapper<BsFanganInfo>()
            .eq(BsFanganInfo::getExcelTypeId, bo.getExcelTypeId())
            .eq(BsFanganInfo::getSysYesNo, "Y"));
        if (ObjUtil.isNull(sysFangan)) {
//            throw new ServiceException("没查到" + bo.getExcelTypeId() + " 的系统方案");
            return ListUtil.empty();
        }
        List<BaFanganDetailVo> detailVos = queryById(sysFangan.getFanganId()).getDetailVos();
        Assert.notEmpty(detailVos, "系统方案不应该没有详细");
        return BeanUtil.copyToList(detailVos, BaFanganYuesheVo.class);
    }

    /**
     * 查询当前使用的方案
     * 选定的方案>试验室默认方案>系统默认方案>没有方案。
     */
    @Override
    public BsFanganInfoVo getFactUseFangan(UseFanganQueryBo bo) {
        FanganUseInfoVo itsVo = fanganUseInfoMapper.selectVoOne(new LambdaQueryWrapper<FanganUseInfo>().eq(FanganUseInfo::getExcelId, bo.getExcelId()));
        if (ObjUtil.isNotNull(itsVo)) {
            return queryById(itsVo.getFanganId());
        }
        BsFanganInfoVo deptDefaultVo = baseMapper.selectVoOne(new LambdaQueryWrapper<BsFanganInfo>()
            .eq(BsFanganInfo::getDeptId, bo.getDeptId())
            .eq(BsFanganInfo::getExcelTypeId, bo.getExcelTypeId())
            .eq(BsFanganInfo::getDefaultFlag, 1));
        if (ObjUtil.isNotNull(deptDefaultVo)) {
            return queryById(deptDefaultVo.getFanganId());
        }
        BsFanganInfoVo sysVo = baseMapper.selectVoOne(new LambdaQueryWrapper<BsFanganInfo>()
            .eq(BsFanganInfo::getExcelTypeId, bo.getExcelTypeId())
            .eq(BsFanganInfo::getSysYesNo, "Y"));
        if (ObjUtil.isNotNull(sysVo)) {
            return queryById(sysVo.getFanganId());
        }
        return null;
//        Assert.notNull(sysVo, "excelTypeId:" + bo.getExcelTypeId() + "deptId:" + bo.getDeptId() + "没有默认的小数点方案");
    }
}
